package com.code.generator;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.func.Supplier2;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiRobotSendRequest;
import com.dingtalk.api.response.OapiRobotSendResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.sql.Types;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 *
 * </p>
 *
 * @author chw
 * @date 2025/3/16
 */
public class Main {
    public static final String mysql_url = "jdbc:mysql://localhost:3306/db_code?useUnicode=true&characterEncoding=UTF-8";
    public static final String mysql_username = "root";
    public static final String mysql_pwd = "root";
    public static final String CREATED_TIME = "created_time";
    public static final String UPDATE_TIME = "updateTime";
    public static final String UPDATED_BY = "updated_by";
    public static final String CREATED_BY = "created_by";
    public static final String ID = "id";
    public static final String VERSION = "version";
    public static final String DELETED = "deleted";
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public String url = "https://oapi.dingtalk.com/robot/send?access_token=e8b14d962374cbf4aced11c1100b71a3fa6b9313ab2b12a322e14606a9951029";

    public static void main(String[] args) throws Exception {
        System.out.println("Hello, World!");
        Main main = new Main();
        main.sendMessageWebhook("【提醒】", "测试第一行", "测试第二行");
    }

    public static Date truncateMilliseconds(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    //"#### 杭州天气 @150XXXXXXXX \n> 9度，西北风1级，空气良89，相对温度73%\n> ![screenshot](https://img.alicdn.com/tfs/TB1NwmBEL9TBuNjy1zbXXXpepXa-2400-1218.png)\n> ###### 10点20分发布 [天气](https://www.dingtalk.com) \n"
    public void sendMessageWebhook(String title3, String... args) throws Exception {
        String contTitle = "#### ".concat(title3).concat("\n ---- \n");
        String join = String.join("\n\n", args);
        String content = contTitle.concat(join).concat("\n");
        DingTalkClient client = new DefaultDingTalkClient(getClientUrl());
        OapiRobotSendRequest request = new OapiRobotSendRequest();
        request.setMsgtype("markdown");
        OapiRobotSendRequest.Markdown markdown = new OapiRobotSendRequest.Markdown();
        markdown.setTitle(title3);
        markdown.setText(content);
        request.setMarkdown(markdown);
        log.info("钉钉消息发送: 【{}】", JSONUtil.toJsonStr(request));
        OapiRobotSendResponse response = client.execute(request);
        log.info("钉钉消息发送结果：{}", response.getBody());
    }

    public String getClientUrl() throws Exception {
        long timestamp = System.currentTimeMillis();
        String suiteSecret = "SEC0432ddf3522e61d8d628cdfb5eb4ec7a25d07649d41b84b972c94aa744a58ed5";
        String stringToSign = timestamp + "\n" + suiteSecret;
        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(suiteSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        String sign = URLEncoder.encode(Base64.encode(signData), "UTF-8");

        return url.concat("&timestamp=").concat(String.valueOf(timestamp)).concat("&sign=").concat(sign);
    }

    public void test8() {
        String exceptionMessage = "status 400 reading ExpensePolicyFeign#writeOffImportApply(WriteOffImportPreParam); content:\n" +
                "{\"ecode\":211049,\"emsg\":\"核报管理中心申请核销金额异常 [{0}]\",\"frontTips\":null}";
        String errAfter = StrUtil.subAfter(exceptionMessage, "content:", false);
        JSONObject jsonObject = JSONUtil.parseObj(errAfter);
        String emsg = jsonObject.get("emsg").toString();
        System.out.println(emsg);
    }

    public void test7(String amountStr) {
        String regex = "^([1-9]\\d*(\\.\\d{1,2})?|0\\.([1-9]\\d?|\\d[1-9]))$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(amountStr);
        boolean matches = matcher.matches();
        System.out.println(matches);
    }

    public void test6() {
        List<Long> collect = Stream.of(2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L).collect(Collectors.toList());
        System.out.println(collect);
        log.info("{}", collect);
    }

    public void test5() {
        String dateStr = "2025-03-16 00:00:00";
        String dateStr2 = "2025-03-16 00:00:00.123";
        DateTime date1 = DateUtil.parse(dateStr);
        DateTime date2 = DateUtil.parse(dateStr2);
        LocalDateTime localDateTime1 = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().withNano(0);
        LocalDateTime localDateTime2 = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime().withNano(0);
        System.out.println(localDateTime1.isEqual(localDateTime2));
        System.out.println(localDateTime1.isAfter(localDateTime2));
        Date date = truncateMilliseconds(date2);
        System.out.println(date);
    }

    public void test4() {
        String xmlStr = "<?xml version='1.0' encoding='utf-8' ?>\n" +
                "<Error>\n" +
                "\t<Code>NoSuchKey</Code>\n" +
                "\t<Message>The specified key does not exist.</Message>\n" +
                "\t<Resource>/50x.html</Resource>\n" +
                "\t<RequestId>NjdmM2NhZThfOTRmNTI3MDlfZTNiZV8xZjRjYTY1OA==</RequestId>\n" +
                "\t<TraceId>OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OWVjYTU1YTQxYjIzY2EyNTc2ZmY2NzFlOWU4NzBkOTFlMTk3MzIyOGNiNzJjYWI5OTEyMzRjYWU4Nzk3NjYwNTg=</TraceId>\n" +
                "</Error>\n" +
                "\n";
        System.out.println(xmlStr.contains("<Error>"));
        System.out.println(xmlStr.startsWith("<?xml"));
    }

    public void test3() {
        Supplier2<List<WineItemVO>, String, String> json2WineItem = ConvertFunc::json2WineItem;
        String jsonStr = "[{\"id\":\"1903298797952905216\",\"tasteProductCode\":\"4000001717\",\"tasteProductName\":\"五粮春/二代系列/(211)45%vol 500mL×6\",\"num\":1,\"spec\":\"500mL×6\",\"totalAmount\":1200},{\"id\":\"1903298797952905217\",\"tasteProductCode\":\"4000001939\",\"tasteProductName\":\"五粮春/二代系列/(211)39%vol 500mL×6\",\"num\":2,\"spec\":\"500mL×6\",\"totalAmount\":2988}]";
        List<WineItemVO> wineItemVOS = json2WineItem.get(jsonStr, "5000001717");
        System.out.println(Arrays.asList(wineItemVOS));
    }

    public void test2() {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入表名，多个英文逗号分隔？所有输入 all");
        FastAutoGenerator.create(mysql_url, mysql_username, mysql_pwd)
                .globalConfig(builder -> builder
                        .author("Chw")
                        .enableSwagger()
                        .disableOpenDir()// 禁止打开输出目录
                        .outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java")
                        .commentDate("yyyy-MM-dd")
                )
                .dataSourceConfig(builder ->
                        builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                            int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                            if (typeCode == Types.SMALLINT) {
                                // 自定义类型转换
                                return DbColumnType.INTEGER;
                            }
                            return typeRegistry.getColumnType(metaInfo);
                        })
                )
                .packageConfig(builder -> builder
                        .parent("com.baomidou.mybatisplus")
                        .moduleName("test")
                        .entity("entity")
                        .mapper("mapper")
                        .service("service")
                        .serviceImpl("service.impl")
                        .xml("mapper.xml")
                        .pathInfo(Collections.singletonMap(OutputFile.xml
                                , System.getProperty("user.dir") + "/src/main/resources/mapper"))
                )
                .strategyConfig(builder -> {
                            builder.entityBuilder()
                                    .superClass(BaseEntity.class)
                                    .enableLombok()
                                    .enableTableFieldAnnotation()
                                    .enableChainModel()
                                    .enableRemoveIsPrefix()
                                    .addTableFills(new Column(CREATED_TIME, FieldFill.INSERT))
                                    .addTableFills(new Property(UPDATE_TIME, FieldFill.INSERT_UPDATE))
                                    .versionColumnName(VERSION)
                                    .logicDeleteColumnName(DELETED)
                                    .addSuperEntityColumns(ID, CREATED_BY, CREATED_TIME, UPDATED_BY, UPDATE_TIME)
                                    .enableFileOverride()
                            ;
                            builder.addInclude(getTables(scanner.nextLine()))
                                    .controllerBuilder()
                                    .enableRestStyle();
                            builder.controllerBuilder().enableFileOverride();
                            builder.serviceBuilder().enableFileOverride();
                            builder.mapperBuilder().enableFileOverride();

                        }
                )
                .templateEngine(new FreemarkerTemplateEngine())
                .templateConfig(builder -> {
                    builder
//                            .xml("/templates/mapper.xml")
//                            .serviceImpl("/templates/serviceImpl.java")
                            .controller("templates/controller.java")
                            .build();
                })
                .execute();
    }

    // 处理 all 情况
    protected List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }


}